Skip to content

Conversation

mbissa
Copy link
Contributor

@mbissa mbissa commented Sep 1, 2025

Fixes #8486

When a gRPC response is received with content type application/grpc, we then do not expect any information in the http status and the status information needs to be conveyed by gRPC status only.

In case of missing gRPC status, we will throw an Internal error instead of Unknown in accordance with https://grpc.io/docs/guides/status-codes/

Changes :
- Ignore http status in case of content type application/grpc
- Change the default rawStatusCode to return Internal for missing grpc status

RELEASE NOTES:

  • client : Ignore the HTTP header status for gRPC streams and return Internal error for missing gRPC status.

Fixes grpc#8486

When a gRPC response is received with content type application/grpc,
we then do not expect any information in the http status and the status information
needs to be conveyed by gRPC status only.

In case of missing gRPC status, we will throw an Internal error instead of Unknown
in accordance with https://grpc.io/docs/guides/status-codes/

	Changes :
	- Ignore http status in case of content type application/grpc
	- Change the default rawStatusCode to return Internal for missing grpc status

RELEASE NOTES:
* client : Ignore http status for gRPC mode and return Internal error for
missing grpc status
@mbissa mbissa added this to the 1.76 Release milestone Sep 1, 2025
@mbissa mbissa requested a review from arjan-bal September 1, 2025 06:27
@mbissa mbissa self-assigned this Sep 1, 2025
Copy link

codecov bot commented Sep 1, 2025

Codecov Report

❌ Patch coverage is 92.30769% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.90%. Comparing base (9ff80a7) to head (09cf708).
⚠️ Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
internal/transport/http2_client.go 92.30% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8548      +/-   ##
==========================================
- Coverage   81.96%   81.90%   -0.06%     
==========================================
  Files         415      415              
  Lines       40694    40690       -4     
==========================================
- Hits        33355    33328      -27     
- Misses       5950     5985      +35     
+ Partials     1389     1377      -12     
Files with missing lines Coverage Δ
internal/transport/http2_client.go 91.91% <92.30%> (+0.41%) ⬆️

... and 22 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@arjan-bal
Copy link
Contributor

In the grpc-go repo, we use the assignee to indicate who the review is pending on (author or reviewer). We ignore the reviewer status (the yellow pending re-review dot). Assigning to myself.

@arjan-bal arjan-bal assigned arjan-bal and unassigned mbissa Sep 1, 2025
@mbissa mbissa requested a review from dfawley September 1, 2025 06:34
@arjan-bal
Copy link
Contributor

arjan-bal commented Sep 1, 2025

For the PR title, we add the name of the Go package (e.g. transport), with the prefix if it's ambiguous (e.g. xds/bootstrap), followed by the change description as a complete sentence, written as though it were an order (an imperative sentence), see go/cl-descriptions#first-line.

@arjan-bal arjan-bal assigned dfawley and unassigned arjan-bal Sep 1, 2025
@dfawley dfawley removed their assignment Sep 3, 2025
@mbissa mbissa force-pushed the ignore-status-for-grpc-content-type-8486 branch 2 times, most recently from e1f6dbc to f123124 Compare September 9, 2025 04:31
@mbissa mbissa force-pushed the ignore-status-for-grpc-content-type-8486 branch from f123124 to b4cce55 Compare September 9, 2025 04:34
@arjan-bal arjan-bal changed the title ignoring http status when content type is application/grpc grpc#8486 client : Ignore http status for gRPC mode and return Internal error for missing grpc status Sep 10, 2025
@arjan-bal arjan-bal assigned arjan-bal and dfawley and unassigned mbissa Sep 10, 2025
@mbissa mbissa changed the title client : Ignore http status for gRPC mode and return Internal error for missing grpc status client : Ignore http status for gRPC mode Sep 10, 2025
@mbissa mbissa changed the title client : Ignore http status for gRPC mode client transport : ignore http status for gRPC mode Sep 10, 2025
@mbissa mbissa removed the request for review from dfawley September 10, 2025 17:59
// headerError is set if an error is encountered while parsing the headers
headerError string
headerError string
receivedHTTPStatus string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: We can omit the received prefix int the variable name, shortening it to httpStatus since it doesn't effect readability.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping on this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

Comment on lines 1524 to 1525
case "200":
grpcErrorCode = codes.Unknown
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this explicit check required? Since 200 isn't present in the HTTPStatusConvTab map, I think it may be omitted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is when no error information can be derived from http status since it is 200, we can simply return Unknown code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default case also adds a error message which seems useful. I think we should remove the special case unless it requires different handling in code. We don't need to worry too much about optimizing the error case, since they're expected to be infrequent.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1; please remove special cases when possible most of the time. Less code = easier to understand code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

@arjan-bal arjan-bal assigned mbissa and unassigned arjan-bal Sep 11, 2025
@arjan-bal arjan-bal changed the title client transport : ignore http status for gRPC mode client: ignore http status header for gRPC mode Sep 15, 2025
@arjan-bal arjan-bal changed the title client: ignore http status header for gRPC mode client: ignore http status header for gRPC streams Sep 15, 2025
Copy link
Contributor

@arjan-bal arjan-bal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly LGTM, left a few minor comments.

Comment on lines 1524 to 1525
case "200":
grpcErrorCode = codes.Unknown
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default case also adds a error message which seems useful. I think we should remove the special case unless it requires different handling in code. We don't need to worry too much about optimizing the error case, since they're expected to be infrequent.

// headerError is set if an error is encountered while parsing the headers
headerError string
headerError string
receivedHTTPStatus string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping on this.

@arjan-bal arjan-bal removed their assignment Sep 15, 2025
// headerError is set if an error is encountered while parsing the headers
headerError string
headerError string
receivedHTTPStatus string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Comment on lines 1524 to 1525
case "200":
grpcErrorCode = codes.Unknown
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1; please remove special cases when possible most of the time. Less code = easier to understand code.

@dfawley dfawley removed their assignment Sep 16, 2025
@Pranjali-2501 Pranjali-2501 modified the milestones: 1.76 Release, 1.77 Sep 17, 2025
@mbissa mbissa force-pushed the ignore-status-for-grpc-content-type-8486 branch from 9c920c8 to 734cd4d Compare September 17, 2025 09:00
Copy link
Member

@dfawley dfawley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delays! The code changes mostly LGTM but I have some bigger comments about the tests.

@dfawley dfawley removed their assignment Oct 1, 2025
@mbissa mbissa force-pushed the ignore-status-for-grpc-content-type-8486 branch from a4c1366 to 09cf708 Compare October 8, 2025 16:20
@dfawley dfawley assigned dfawley and unassigned mbissa Oct 8, 2025
Copy link
Member

@dfawley dfawley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor things, otherwise LGTM


test.metaHeaderFrame.HeadersFrame = &http2.HeadersFrame{
// TestClientDecodeTrailer validates the handling of trailer frames, which may
// or may not also be the initial header frame (header-only response).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// or may not also be the initial header frame (header-only response).
// or may not also be the initial header frame (trailers-only response).

Terminology from https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#responses

Comment on lines +2833 to +2835
// Mark headerChanClosed to indicate trailer frames.
cs.headerChanClosed = 1
// Simulate the state where the initial headers have already been processed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both of these comments seem like they're related to the same thing, which is setting headerChanClosed.

}{
{
name: "missing gRPC status",
name: "missing gRPC content type",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like you have changed this test instead of adding a new one? Shouldn't we still have a test that sets these exact header fields?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing grpc status is no longer relevant in the the initial headers - it is tested in the trailers test where grpc status is expected/mandatory.

},
{
name: "malformed grpc-status-details-bin field with status 200",
name: "malformed grpc-status-details-bin field with status 404 and no content type",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar - don't we still want to have a test with an illegal grpc-status-details-bin and status 200? We can also have this new test case, but it seems like having more test cases is always better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the content type is application/grpc (as was in previous version of the test) the http status is immaterial (200/404 etc won't make a difference) and it is tested in the test case above this with 404. This was more important variation of data where we check without correct content type.

@dfawley dfawley assigned mbissa and unassigned dfawley Oct 8, 2025
@mbissa mbissa merged commit 04a7af2 into grpc:master Oct 8, 2025
15 checks passed
@mbissa mbissa deleted the ignore-status-for-grpc-content-type-8486 branch October 8, 2025 20:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

client transport: ignore HTTP/2 status if content-type is application/grpc
4 participants